﻿// ----------------------------------------------------------------------------------
// <copyright file="StructureMapUseCaseTest.cs" company="Christopher Hines">
// Copyright (c) 2012 All Right Reserved
// </copyright>
// <author>Chris Hines</author>
// <date>2012-03-23</date>
// <summary>
//     Unit tests for a standard StructureMap configuration
// </summary>
// ----------------------------------------------------------------------------------

namespace Copperfield.UseCases.Test
{
    using Copperfield;
    using Copperfield.Demo.Common;
    using Copperfield.Demo.Models;
    using Copperfield.Sdk;

    using FluentAssertions;

    using Microsoft.VisualStudio.TestTools.UnitTesting;

    using StructureMap;

    /// <summary>
    /// Unit tests for a standard StructureMap configuration
    /// </summary>
    [TestClass]
    public class StructureMapUseCaseTest
    {
        /// <summary>
        /// Gets or sets the test context
        /// </summary>
        /// <value>
        /// The test context
        /// </value>
        public TestContext Context { get; set; }

        /// <summary>
        /// Gets or sets the context manager
        /// </summary>
        /// <value>
        /// The context manager
        /// </value>
        private static ContextManagerBase<SignContext> ContextManager { get; set; }

        /// <summary>
        /// Initializes the test class
        /// </summary>
        /// <param name="context">
        /// The test context
        /// </param>
        [ClassInitialize]
        public static void ClassInitialize(TestContext context)
        {
            ObjectFactory.Initialize(x =>
                                         {
                                             x.Scan(scan =>
                                                        {
                                                            scan.TheCallingAssembly();
                                                            scan.WithDefaultConventions();
                                                        });

                                             CopperfieldConfiguration.InstancesAreResolvedBy(ObjectFactory.GetInstance);
                                             
                                             CopperfieldConfiguration.ConfigurePluginInstances((pluginType, contextType, frameworkDelegate) => 
                                                 x.For(pluginType).Use(c => frameworkDelegate(pluginType, contextType)));

                                             x.For<ContextManagerBase<SignContext>>().Use<NonWebContextManager<SignContext>>();
                                         });

            ContextManager = ObjectFactory.GetInstance<ContextManagerBase<SignContext>>();
        }

        /// <summary>
        /// A unit test for a pedestrian sign
        /// </summary>
        [TestMethod]
        public void StructureMap_Standard_Configuration_DefaultSignTest()
        {
            SetContext(SignColor.Unknown, SignShape.Unknown, SignText.Unknown);

            var sign = ObjectFactory.GetInstance<IStreetSign>();

            sign.Should().BeOfType<DefaultSign>();
        }

        /// <summary>
        /// A unit test for a speed limit sign
        /// </summary>
        [TestMethod]
        public void StructureMap_Standard_Configuration_SpeedLimitSignTest()
        {
            SetContext(SignColor.White, SignShape.Rectangle, SignText.SpeedLimit);

            var sign = ObjectFactory.GetInstance<IStreetSign>();

            sign.Should().BeOfType<SpeedLimitSign>();
        }

        /// <summary>
        /// A unit test for a pedestrian sign
        /// </summary>
        [TestMethod]
        public void StructureMap_Standard_Configuration_HospitalSignTest()
        {
            SetContext(SignColor.Blue, SignShape.Rectangle, SignText.Hospital);

            var sign = ObjectFactory.GetInstance<IStreetSign>();

            sign.Should().BeOfType<HospitalSign>();
        }

        /// <summary>
        /// A unit test for a pedestrian sign
        /// </summary>
        [TestMethod]
        public void StructureMap_Standard_Configuration_StopSignTest()
        {
            SetContext(SignColor.Red, SignShape.Octagon, SignText.Stop);

            var sign = ObjectFactory.GetInstance<IStreetSign>();

            sign.Should().BeOfType<StopSign>();
        }

        /// <summary>
        /// A unit test for a pedestrian sign
        /// </summary>
        [TestMethod]
        public void StructureMap_Standard_Configuration_RailroadCrossingSignTest()
        {
            SetContext(SignColor.Yellow, SignShape.Circle, SignText.Railroad);

            var sign = ObjectFactory.GetInstance<IStreetSign>();

            sign.Should().BeOfType<RailroadCrossingSign>();
        }

        /// <summary>
        /// A unit test for a pedestrian sign
        /// </summary>
        [TestMethod]
        public void StructureMap_Standard_Configuration_PedestrianSignTest()
        {
            SetContext(SignColor.Yellow, SignShape.Square, SignText.Pedestrians);

            var sign = ObjectFactory.GetInstance<IStreetSign>();

            sign.Should().BeOfType<PedestrianWarningSign>();
        }

        /// <summary>
        /// Sets the sign context values
        /// </summary>
        /// <param name="color">
        /// The color.
        /// </param>
        /// <param name="shape">
        /// The shape.
        /// </param>
        /// <param name="signText">
        /// The sign text.
        /// </param>
        private static void SetContext(SignColor color, SignShape shape, string signText)
        {
            var context = ContextManager.GetContext() ?? new SignContext();

            context.Color = color;
            context.Shape = shape;
            context.Text = signText;

            ContextManager.SetContext(context);
        }
    }
}
